package codename.carrot.bomberman.models;

import sheep.game.Sprite;
import sheep.graphics.Image;
import android.graphics.Canvas;
import codename.carrot.bomberman.AppStorage;
import codename.carrot.bomberman.game.listener.ObstacleListener;

/**
 * Abstract class that is used by the game's obstacles that doesn't require animations
 * @see {@link codename.carrot.bomberman.models.AbstractAnimatedObstacle} - Abstract class for animated obstacles
 * @author Group A4
 *
 */
public abstract class AbstractObstacle extends Sprite {
	
	/**
	 * The x-coordinate for this obstacle
	 */
    private int xCoorMap, 
	/**
	 * the y-coordinate for this obstacle
	 */
    yCoorMap;
	/**
	 * the listener of this obstacle
	 */
    private ObstacleListener listener;
	/**
	 * the visibility of this obstacle
	 */
    private boolean visible=false;
	/**
	 * tells whether the obstacle has exploded or not
	 */
    private boolean hasExploded = false;    
    
    /**
     * Constructor for class, for objects with attached listener
     * @param xCoor - X coordinates to spawn the obstacle at
     * @param yCoor - Y coordinates to spawn the obstacle at
     * @param image - Image to be used for the obstacle
     * @param listener - obstacle listener
     */
    public AbstractObstacle(int xCoor, int yCoor, Image image, ObstacleListener listener) {
        super(image);        
        this.xCoorMap = xCoor;
        this.yCoorMap = yCoor;
        this.listener = listener;        
        setPosition(xCoor*AppStorage.TILE_SIZE+AppStorage.TILE_SIZE/2, yCoor*AppStorage.TILE_SIZE+AppStorage.TILE_SIZE/2);  
    }     
    
    /**
     * Constructor for class, for objects without attached listener
     * @param xCoor - X coordinates to spawn the obstacle at
     * @param yCoor - Y coordinates to spawn the obstacle at
     * @param image - Image to be used for the obstacle
     */
    public AbstractObstacle(int xCoor, int yCoor, Image image) {
        this(xCoor, yCoor, image, null);
    }
    
	/**
	 * Returns whether this obstacle is destructible or not
	 */
    public abstract boolean isDestructible();
    
    /**
     * Checks for whether a bomb has already exploded
     * @return hasExploded - true/false value
     */
    public boolean hasExploded() {
        return hasExploded;
    }
    
    
    /**
     * @param otherSprite - Sprite of the obstacle this obstacle has collided with
     * @return super.collides(otherSprite) - true/false collision generated by the Sheep Sprite class
     * @see {@link sheep.game.Sprite}
     */
    @Override
    public boolean collides(Sprite otherSprite) {
        if(!visible) return false;
        return super.collides(otherSprite);
    }
    
    /**
     * Returns the status of this object's visibility attribute
     * @return visible - true/false
     */
    public boolean isVisible() {
        return visible;
    }
    
    /**
     * Alters the visibility parameter of the current object
     * @param visible - the true/false value to set for this object's visibility parameter
     */
    public void setVisible(boolean visible) {
        this.visible = visible;
        fireVisible(this,visible);
    }
    
    /**
     * Informs the listeners that the object has changed it's visibility parameter
     * @param abstractObstacle - the applicable object
     * @param visible - the new boolean value for the object's visibility parameter
     */
    private void fireVisible(AbstractObstacle abstractObstacle, boolean visible) {
        if(listener != null)
            listener.onObstacleVisibilityChanged(abstractObstacle, visible);		
	}

    /**
     * Getter for the current object's X-coordinates
     * @return xCoorMap - the current objects X-coordinates
     */
	public int getXcoorMap() {
        return xCoorMap;
    }
    
    /**
     * Getter for the current object's Y-coordinates
     * @return yCoorMap - the current objects Y-coordinates
     */
    public int getYcoorMap() {
        return yCoorMap;
    }          
    
    /**
     * Setter for the current object's X-coordinates
     * @param xCoorMap - new X-coordinates for the current object
     */
    public void setXcoorMap(int xCoorMap) {
    	this.xCoorMap = xCoorMap; 
    }
    
    /**
     * Setter for the current object's Y-coordinates
     * @param yCoorMap - new Y-coordinates for the current object
     */
    public void setYcoorMap(int yCoorMap) {
    	this.yCoorMap = yCoorMap; 
    }
     
	/**
	 * Informs attached listeners that the object is exploding
	 */
    public void fireObstacleExplodes() {
        if(listener != null && !hasExploded) {
            hasExploded = true;
            listener.onObstacleExploded(this);   
        }
    }     
    
    /**
     * Informs the attached listeners that the object should be removed
     */
    public void fireRemoveObstacle() {
        if(listener != null)
            listener.onRemoveObstacle(this);
    }
    
    /**
     * Informs the attached listeners that the object's visibility attribute changed
     */
    public void fireObstacleVisibilityChanged() {
        if(listener != null)
            listener.onObstacleVisibilityChanged(this, true);
    }
    
    /**
     *  Draws the current object if the object should in fact be visible
     *  @param canvas - the (default) canvas on which to draw the object
     */
    @Override
    public void draw(Canvas canvas) {
    	if(canvas == null) return;
        if(visible) super.draw(canvas);
    }
}
